<?php
declare(strict_types=1);

namespace lib;

use lib\data\Goods;
use lib\data\StoreComponents;
use lib\data\virtual\GoodsOrder;
use sys\Log;

class Merchant extends \lib\sync\SyncableData {

    const PROD_FREE     = 0;        # 免费版
    const PROD_VIP      = 1;        # 收费版

    use \lib\data\traits\UnikTrait;
    use \lib\data\traits\WaitLock;

    protected static string $SyncKey = 'Merchant';
    public int $id;
    public int $agent;
    public string $name;
    public string $prod;
    public int $uid;
    public bool $freeze;
    public int $createtime;

    # 网吧平台的节点地址
    public int $sid;


    public array $channels = [];
    protected ?\lib\data\Shift $shift = null;
    
    protected static array $propNamesC = ['id', 'agent', 'name','prod','uid','freeze','sid' ];
    protected static array $propNamesU = ['id', 'agent', 'name','prod','uid','freeze','sid' ] ;
    protected static array $propNamesJ = ['id', 'agent', 'name','prod','uid','freeze','sid' ] ;

    public function __construct(array $data)
    {
        parent::__construct($data);
        $this->traitInit();
    }

    public static function alwaysFullSync() : bool { return true;}

    public static function getAll(int $id): array {
        return [static::$pk[$id]] ?? [];
    }

    public static function initMerchants(array $mids){
        if(count($mids) == 0) return;
        $db = new \sys\Db();

        $opt = ['mid', 'IN', $mids];
        $all_merchants = $db->table('el_merchant')
            ->where([['el_merchant.id','IN', $mids]])->field([
                'el_merchant.id',
                'el_merchant.uid',
                'el_merchant.name',
                'el_merchant.prod',
                'el_merchant.agent',
                'el_merchant.sid',
                'el_merchant.freeze',
                'el_merchant.createtime'
            ])->select();

        $all_users = $db->table('el_user_role,el_user')
            ->join('el_user','el_user.id=el_user_role.uid')
            ->field([
                'el_user.id',
                'el_user.username',
                'el_user_role.mid AS mid',
                'el_user_role.role_id',
                'el_user_role.roles',
            ])->where(['el_user_role.mid','IN', $mids])->select();

        $all_data_version = $db->table('el_dataversion')->where($opt)->order('id ASC')->select() ?? [];
        $cats = $db->table('el_category')->where($opt)->order('sortid ASC')->select();

        # 构建数据对象
        \lib\sync\Synchronize::setVersions($all_data_version);

        # 创建商户对象
        foreach($all_merchants as $m){
            $merchant = new \lib\Merchant($m);
        }

        Log::console(json_encode($cats, JSON_UNESCAPED_UNICODE),'DEBUG');
        array_to_object($all_users, \lib\User::class, true);
        array_to_object($cats, \lib\data\Category::class, true);

    }

    /*
        加载商户初始数据
    */
    public static function init(int $workerId) {
        $db = new \sys\Db();
        $mids = array_column($db->table('el_merchant')->where([['agent','=', 0], ['sid','=', $workerId]])->field('id')->select()??[], 'id');
        static::initMerchants($mids);
    }
    
    public function addChannel(\sys\services\JsonWebSocket $ws){
        $this->channels[spl_object_id($ws)] = $ws;
    }

    public function removeChannel(\sys\services\JsonWebSocket $ws){
        unset($this->channels[spl_object_id($ws)]);
        if(empty($this->channels)){
            $this->channels = [];
        }
    }

    public function call(string $action, null|array $data, int $timeout, \Closure $update) : array {
        foreach($this->channels as $ws){
            /** @var \sys\services\JsonWebSocket $ws */
            return $ws->call($action, $data, $timeout, $update);
        }
        return ['success'=>false, 'message'=>'商户离线.'];
    }

    public function push(array $msg){
        foreach($this->channels as $ws){
            $ws->push($msg);
        }
    }

    public function getPayUrl(): string {
        return "https://elec-{$this->sid}.exti.cc";
    }
}